home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Pascal Super Library
/
Pascal Super Library (CW International)(1997).bin
/
PGM_TOOL
/
PREVIEW
/
CLP2DLFI
/
DL.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1995-10-29
|
74KB
|
2,394 lines
Unit wdl;
Interface
Uses Classes, SysUtils, DBFserver, CommonCode, wPreview;
const
TABWIDTH=2;
MAXCHK=70;
CHARLIST='abcdefghijklmnopqrstuvwxyz0123456789_()><=+, '+
'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
DELIMLIST='()><=+, ';
LASTCHAR='abcdefghijklmnopqrstuvwxyz0123456789_'+
'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
type oDL=Class(TObject)
private
done,endline:boolean;
mxronly,runsilent,usemxr,valchk,wasmxr:boolean;
acnt,chgcnt,dcnt,ii10,ii7,ii8,ii9,indent,mxrcnt,pii:integer;
passlev,curline,subscnt,tparscnt,xcnt:integer;
acom,afterchk,comstr,errfile,errmess,line1,line2,org:string;
org2,tst,orgstr,orgtst,pc0,pc1,pc2,retstr,temp1,temp2,temp3:string;
tab,crlf,errport:string10;
curfunc:string20;
srcfile,destfile:string80;
hascase,hasdoproc,hasif,haswhile,hasfor,hasrepeat:integer;
hadget,hasuntil,simplecnt,latecnt,cmplxcnt,proccnt:integer;
inproc,hadsemi,hasdowith:boolean;
linecnt:integer;
mxlist:array [1..10] of string;
mxorg:array [1..10] of string;
dlist:array [1..15] of string135;
plist:array [1..30] of string135;
rlist:array [1..30] of string135;
equl:array [1..50] of string135;
saveline:array [1..6] of boolean;
ats:array [1..80] of integer;
tpars:array [1..80] of string135;
cmplx:array [1..MAXCHK,1..2] of string30;
late:array [1..MAXCHK,1..2] of string30;
simple:array [1..MAXCHK,1..2] of string30;
proc0arg:array [1..MAXCHK] of string30;
proc1arg:array [1..MAXCHK] of string30;
proc2arg:array [1..MAXCHK] of string30;
proctest:array [1..MAXCHK] of string30;
inlines,outlines,flist,xarr:tstringlist;
defines,prvlist,publist:tstringlist;
out:lpr;
fields:oDB;
function argchk(orgstr,srchfor,has0arg,
has1arg,has2arg:string):string;
function chkline(wasmxr:boolean):boolean;
function fixline:boolean;
function fldconv(orgstr:string):string;
function mdxconv:boolean;
function getline(var aStr:string):boolean;
procedure AddCmplx(s1,s2:string);
procedure AddLate(s1,s2:string);
procedure AddSimple(s1,s2:string);
procedure cnvrt(passlev:integer);
procedure convmxr(var astr:string;var waschg:boolean);
procedure delfi2(subnum:integer;themodule,aline:string);
procedure delphiconv;
procedure putline(aStr:string);
procedure initarrs(fordbw:boolean); { INITARRS }
procedure loadflds(dpath:string);
procedure nuline(orgstr,line1,line2:string;
var equallist:array of string135;var ecnt:integer);
procedure savevar(mn,cn,vn,xn,fn,dn:string);
procedure AddProc(ftest,a0,a1,a2:string);
procedure CleanUpDelphi;
function CapFirstChar(aStr:string):string;
procedure SaveOther(srcf:string);
procedure ParsVars(srcf,ext:string;tStr:TStringlist);
procedure threepcs(var tindent:integer;
var tretstr,tacomment:string);
public
doDBWconv:boolean;
constructor Create;
procedure Free;
procedure dbase2delphi(curdir,srcf:string);
end;
Implementation
uses NuDelphi;
constructor oDL.Create;
begin
fields:=nil;
dodbwconv:=true;
inlines:=TStringlist.Create;
outlines:=TStringlist.Create;
flist:=TStringlist.Create;
xarr:=TStringlist.Create;
prvlist:=TStringlist.Create;
publist:=TStringlist.Create;
defines:=TStringlist.Create;
end;
procedure oDL.Free;
begin
inlines.free;
outlines.free;
flist.free;
xarr.free;
prvlist.free;
publist.free;
defines.free;
end;
procedure oDL.dbase2delphi(curdir,srcf:string);
var ii:integer;
tt:tstringlist;
tt2:string;
begin
dbUseExclusive(fields,InstalledTo+'\fields');
{ load all field info, only do if no entries in file once }
if fields.RecCount=0 then begin
tt:=tstringlist.create;
tt.loadfromfile(InstalledTo+'\dbfdirs.txt');
MouseWait;
if tt.count>0 then begin
for ii:=0 to tt.count-1 do begin
tt2:=tt[ii];
if not empty(tt2) then begin
loadflds(tt2);
end;
end;
end;
MouseGo;
tt.free;
End;
crlf:=chr(13)+chr(10);
comstr:='//';
outlines.clear;
publist.clear;
prvlist.clear;
defines.clear;
linecnt:=0;
{ do dBaseWin conversion first }
srcfile:=noext(srcf)+'.prg';
destfile:=noext(srcf)+'.txt';
if dodbwconv then begin
inlines.LoadFromFile(curdir+'\'+srcfile);
mdxconv;
outlines.savetofile(curdir+'\'+destfile);
srcfile:=destfile; { set srcfile for Delphi conversion to use }
End;
{ do Delphi conversion routine }
destfile:=noext(srcf)+'.pas';
outlines.clear;
linecnt:=0;
inlines.LoadFromFile(curdir+'\'+srcfile);
delphiconv;
cleanupdelphi;
db2dl.progress.caption:='Done With '+ltrim(str(outlines.count,5,0))+' Lines';
outlines.savetofile(curdir+'\'+destfile);
SaveOther(srcf);
dbClose(fields);
end;
function oDL.CapFirstChar(aStr:string):string;
var uu,ll:string;
begin
uu:=upper(astr);
ll:=lower(astr);
result:=substr(uu,1,1)+substr(ll,2,100);
end;
procedure oDL.CleanUpDelphi;
var varsend,procindent,ii,jj,kk,mm,pcnt,p1:integer;
parms,uu,procname,proccom,tt2,p2,p3:string;
invar,inproc:boolean;
plist:array [1..300] of integer;
begin
{ add begin's, end's to procedure and functions }
{ merge "param" line's into procedure heading }
pcnt:=0;
for ii:=0 to outlines.count-1 do begin
uu:=upper(outlines[ii]);
if (pin('PROCED',uu)) or (pin('FUNCT',uu)) then begin
procindent:=0;
procname:=outlines[ii];
proccom:='';
threepcs(procindent,procname,proccom);
mm:=pos(' ',procname);
if mm>0 then begin
tt2:=substr(procname,1,mm);
if pin('FUNCT',uu) then tt2:=tt2+' ';
outlines[ii]:=space(procindent)+tt2+'o'+
CapFirstChar(noext(srcfile))+'.'+substr(procname,mm+1,130)+
proccom;
end;
if pcnt<300 then begin
pp(pcnt);
plist[pcnt]:=ii;
end;
end;
end;
if pcnt>0 then begin { terminate last proc }
pp(pcnt);
plist[pcnt]:=outlines.count-2;
{ do in reverse order because we will be adding lines }
for ii:=(pcnt-1) downto 1 do begin
invar:=false;
kk:=plist[ii+1]-plist[ii];
if kk>20 then kk:=20; { only check first 20 lines }
parms:='';
procindent:=0;
procname:=outlines[plist[ii]];
proccom:='';
threepcs(procindent,procname,proccom);
varsend:=plist[ii];
for jj:=plist[ii] to (plist[ii]+kk) do begin
p1:=0;
p2:=outlines[jj];
p3:='';
threepcs(p1,p2,p3);
uu:=upper(p2);
if (pin('PARAM',uu)) then begin
mm:=pos(' ',p2);
tt2:='';
if mm>0 then begin
tt2:=substr(p2,mm+1,130);
mm:=pos(';',tt2);
if mm>0 then tt2:=substr(tt2,1,mm-1);
tt2:=ltrim(trim(tt2));
end;
if not empty(tt2) then begin
if empty(parms) then parms:=tt2
else parms:=parms+','+tt2;
end;
outlines[jj]:=space(procindent)+'{ parameters moved into header }';
end;
if (pin('LOCAL',uu)) then begin
varsend:=jj;
mm:=pos(' ',p2);
tt2:='';
if mm>0 then begin
tt2:=substr(p2,mm+1,132);
tt2:=ltrim(trim(tt2));
end;
if invar then begin
outlines[jj]:=space(4)+tt2+p3;
end else begin
outlines[jj]:='Var '+tt2+p3;
end;
if not invar then invar:=true;
end;
end;
if not empty(parms) then begin
{ knock off semi-colon on end before adding parameters }
outlines[plist[ii]]:=space(procindent)+
substr(procname,1,length(procname)-1)+'('+parms+');'+proccom;
end;
{ add first "begin" of procedure block }
if empty(outlines[varsend+1]) then
outlines[varsend+1]:=space(procindent)+'Begin'
else outlines.insert(varsend+1,space(procindent)+'Begin');
{ add final "end" of procedure block }
for kk:=(plist[ii+1]-1) downto (plist[ii]) do begin
if not empty(outlines[kk]) then begin
outlines.insert(kk+1,space(procindent)+'End;');
break;
end;
end;
end;
end;
if defines.count>0 then begin
jj:=outlines.count-1;
if jj>20 then jj:=20;
for ii:=0 to jj do begin
p2:=outlines[ii];
threepcs(p1,p2,p3);
if p2='Type' then begin
outlines.insert(ii,'');
for kk:=defines.count-1 downto 0 do begin
tt2:=defines[kk];
tt2:=strtran(tt2,'#define','');
tt2:=ltrim(tt2);
tt2:=strtran(tt2,'"','''');
mm:=pos(' ',tt2);
if mm>0 then tt2[mm]:='=';
outlines.insert(ii,' '+tt2+';');
end;
outlines.insert(ii,'');
outlines.insert(ii,'Const');
break;
end;
end;
end;
end;
procedure oDL.ParsVars(srcf,ext:string;tStr:TStringlist);
var tt:tstringlist;
tt2,p1,p2:string;
ii,jj,kk:integer;
begin
tt:=tstringlist.create;
tt.sorted:=true;
tt.duplicates:=dupIgnore;
for ii:=0 to tstr.count-1 do begin
tt2:=tstr[ii];
tt2:=strtran(tt2,',',' '); { convert comma's to spaces }
split(tt2,' ',pars,parscnt);
for jj:=2 to parscnt do begin { skip first word }
if not empty(pars[jj]) then begin
p1:=upper(pars[jj]);
{ skip declarations }
if pin('PRIVATE',p1) then continue;
if pin('PUBLIC',p1) then continue;
if pin('DECLARE',p1) then continue;
kk:=pos('[',pars[jj]);
if kk>0 then begin
p1:=substr(pars[jj],1,kk-1);
p2:=substr(pars[jj],kk+1,100);
if (jj<parscnt) and (pin(substr(pars[jj+1],1,1),'0123456789'))
then begin
p2:=p2+',1..'+pars[jj+1];
pars[jj+1]:='';
end;
{ put 'zzz' on front of arrays to force to end of list }
pars[jj]:='zzz'+p1+':array [1..'+p2+' of integer;';
end;
if not empty(pars[jj]) then tt.add(pars[jj]);
end;
end;
end;
tt.sorted:=false;
for ii:=0 to tt.count-1 do begin
if pin('array',tt[ii]) then tt[ii]:=substr(tt[ii],4,130);
end;
tt.insert(0,upper(noext(srcf)+' '+ext));
tt.insert(1,'');
tstr.assign(tt);
tt.free;
end;
procedure oDL.SaveOther(srcf:string);
begin
if prvlist.count>0 then begin
ParsVars(srcf,'Private Variable''s',prvlist);
prvlist.savetofile(noext(srcf)+'.prv');
end;
if publist.count>0 then begin
ParsVars(srcf,'Public Variable''s',publist);
publist.savetofile(noext(srcf)+'.pub');
end;
end;
procedure oDL.delphiconv;
var retstr,acomment:array [1..6] of string135;
indent:array [1..6] of integer;
ii,casecnt:integer;
p2,p3:string135;
tt,tst,ustr,orgstr:string;
removed,indocase,addbegin,hadsemi:boolean;
semistr:string10;
caseleft,p1,jj,kk,mm,lcnt,ll:integer;
begin
{ init buffer first }
curline:=1;
{ start processing }
passlev:=1;
comstr:='//';
if passlev=1 then begin { do simple conversions }
for ii:=1 to MAXCHK do begin
for jj:=1 to 2 do simple[ii][jj]:=' ';
for jj:=1 to 2 do late[ii][jj]:=' ';
for jj:=1 to 2 do late[ii][jj]:=' ';
proctest[ii]:=' ';
proc0arg[ii]:=' ';
proc1arg[ii]:=' ';
proc2arg[ii]:=' ';
end;
initarrs(False);
putline('Unit '+lower(noext(srcfile))+';');
putline('');
putline('Interface');
putline('');
putline('Type');
putline('');
putline(space(tabwidth)+'o'+CapFirstChar(noext(srcfile))+
'=Class(TObject)');
putline(space(tabwidth)+'Private');
putline('');
putline(space(tabwidth)+'Public');
putline('');
putline(space(tabwidth)+'End;');
putline('');
putline('Implementation');
putline('');
putline('Uses DBFserver, CommonCode, wPreview;');
putline('');
done:=False;
hascase:=0;
caseleft:=0;
casecnt:=0;
curfunc:=''; { used in DeleteFile() }
if dodbwconv then
db2dl.progress.caption:='Phase 3, Line '+str(curline,5,0)
else
db2dl.progress.caption:='Line '+str(curline,5,0);
While not done do begin
DoEvents2;
for ii:=1 to 6 do begin
indent[ii]:=0;
retstr[ii]:='';
acomment[ii]:='';
saveline[ii]:=True;
end;
lcnt:=0;
{ if a continued line must load all following related lines also }
for ii:=1 to 6 do begin
DoEvents2;
if getline(tst) then begin
retstr[ii]:=tst;
pp(curline);
if (curline mod 100)=0 then begin
if dodbwconv then
db2dl.progress.caption:='Phase 4, Line '+str(curline,5,0)
else
db2dl.progress.caption:='Line '+str(curline,5,0);
end;
p1:=indent[ii];
p2:=retstr[ii];
p3:=acomment[ii];
threepcs(p1,p2,p3);
indent[ii]:=p1;
retstr[ii]:=p2;
acomment[ii]:=p3;
pp(lcnt);
hadsemi:=(Copy(retstr[ii],length(retstr[ii]),1)=';');
if hadsemi then begin
{ cut off ';' from end of line }
retstr[ii]:=Copy(retstr[ii],1,length(retstr[ii])-1);
End Else Begin
break;
End;
end else done:=true;
End;
if not empty(retstr[1]) then begin
ustr:=upper(retstr[1]);
ii:=pos('PRIVATE',ustr);
if ii=0 then ii:=pos('DECLARE',ustr);
if ii=1 then begin
tt:='';
for ll:=1 to lcnt do tt:=tt+' '+retstr[ll];
prvlist.add(tt);
continue; { do not save line in code file }
end else begin
ii:=pos('PUBLIC',ustr);
if ii=1 then begin
tt:='';
for ll:=1 to lcnt do tt:=tt+' '+retstr[ll];
publist.add(tt);
continue; { do not save line in code file }
end else begin
ii:=pos('#DEFINE',ustr);
if ii=1 then begin
defines.add(retstr[1]);
continue; { do not save line in code file }
end;
end;
end;
end;
hasdoproc:=0;
hasif:=0;
haswhile:=0;
hasfor:=0;
hasrepeat:=0;
hasuntil:=0;
hasdowith:=False;
hascase:=0;
for ll:=1 to lcnt do begin
DoEvents2;
semistr:=';';
orgstr:=retstr[ll];
ustr:=upper(retstr[ll]);
ii:=pos(comstr,acomment[ll]);
if ii>0 then begin
acomment[ll]:=stuff(acomment[ll],ii,2,'{');
acomment[ll]:=acomment[ll]+' }';
End;
ii:=pos('; {',acomment[ll]);
if ii>0 then begin
acomment[ll]:=stuff(acomment[ll],ii,2,'{');
acomment[ll]:=acomment[ll]+' }';
End;
addbegin:=False;
{ do not append ";" to if's, while's, for's, repeat's }
if ll=1 then begin
hasdoproc:=pos('DO ',ustr);
hasif:=pos('IF ',ustr);
haswhile:=pos('DO WHILE ',ustr);
hasfor:=pos('FOR ',ustr);
hasrepeat:=pos('REPEAT',ustr);
hasuntil:=pos('UNTIL ',ustr);
End;
hasdowith:=False;
hascase:=pos('CASE',ustr);
if hascase>0 then begin
if pin('END',ustr) then begin
hascase:=0;
caseleft:=0;
casecnt:=0;
hascase:=0;
retstr[ll]:='End';
ustr:=upper(retstr[ll]);
End Else
Begin
if pos('DO',ustr)=1 then begin
hascase:=0;
caseleft:=indent[ll];
saveline[ll]:=False;
End Else
Begin
retstr[ll]:='if'+Copy(retstr[ll],5,100);
hasif:=1;
pp(casecnt);
ustr:=upper(retstr[ll]);
End;
End;
End;
if (hasif=1) Or (haswhile=1) Or (hasfor=1) Or (hasrepeat=1) then begin
semistr:='';
End;
if (hasif=1) Or (haswhile=1) then begin
addbegin:=True;
End;
if (hasif=1) And (ll=lcnt) then begin { on last line, add "then" }
retstr[ll]:=retstr[ll]+' then';
ustr:=upper(retstr[ll]);
End;
{ on last line of "while", add "do" }
if (haswhile=1) And (ll=lcnt) then begin
retstr[ll]:=retstr[ll]+' do';
ustr:=upper(retstr[ll]);
End;
{ on last line of "for", add "do begin" }
if (hasfor=1) And (ll=lcnt) then begin
retstr[ll]:=retstr[ll]+' do begin';
ustr:=upper(retstr[ll]);
End;
{ convert 'set relation' to dbSetRelation }
if pos('SET RELATION',ustr)=1 then begin
split(retstr[ll],' ',pars,parscnt);
retstr[ll]:='dbf.SetRelation('+pars[6]+'.Area,'''+
pars[4]+''')';
ustr:=upper(retstr[ll]);
end;
{ convert "=" to ":=", ignore for boolean }
{ test expressions in if's, while's, until's, case's }
if (pin('=',retstr[ll])) And ((hasfor=1) Or
(not ((hasif=1) Or (haswhile=1) Or (hasuntil=1) Or (hascase>0))))
And (not pin(':=',retstr[ll])) then begin
split(retstr[ll],'=',pars,parscnt);
retstr[ll]:='';
for ii:=1 to parscnt do begin
retstr[ll]:=retstr[ll]+pars[ii];
if ii=1 then begin
retstr[ll]:=retstr[ll]+':=';
End Else
Begin
if ii<parscnt then begin
retstr[ll]:=retstr[ll]+'=';
End;
End;
End;
ustr:=upper(retstr[ll]);
End;
ii:=pos('ELSE',ustr);
if ii=1 then begin
semistr:='';
End;
if ustr='ELSE' then begin
retstr[ll]:='End Else Begin';
ustr:=upper(retstr[ll]);
End;
if (hasdoproc=1) And (haswhile=0) then begin
if pin('WITH',ustr) then begin
hasdowith:=True;
End;
retstr[ll]:=Copy(retstr[ll],4,130);
ustr:=upper(retstr[ll]);
End;
if length(retstr[ll])=0 then begin
semistr:='';
End Else
Begin
{ do simple conversions }
for ii:=1 to SimpleCnt do begin
DoEvents2;
if pin(simple[ii,1],retstr[ll]) then begin
split(retstr[ll],simple[ii,1],pars,parscnt);
retstr[ll]:=pars[1];
for jj:=2 to parscnt do begin
tt:=substr(pars[jj-1],length(pars[jj-1]),1);
if pin(tt,LASTCHAR) then begin
if simple[ii,1]='"' then
retstr[ll]:=retstr[ll]+simple[ii,2]+pars[jj]
else
retstr[ll]:=retstr[ll]+simple[ii,1]+pars[jj];
end else
retstr[ll]:=retstr[ll]+simple[ii,2]+pars[jj];
end;
End;
End;
{ do database command substitutions }
if pos('select',retstr[ll])=1 then begin
split(retstr[ll],' ',pars,parscnt);
for ii:=2 to parscnt do begin
if not empty(pars[ii]) then begin
retstr[ll]:='dbSelect('+pars[ii]+')';
break;
End;
End;
End;
for ii:=1 to ProcCnt do begin
retstr[ll]:=argchk(retstr[ll],proctest[ii],proc0arg[ii],
proc1arg[ii],proc2arg[ii]);
End;
ustr:=upper(retstr[ll]);
{ convert field assignment statements }
retstr[ll]:=fldconv(retstr[ll]);
End;
{ try to convert if's, while's, until's }
if (hasif>0) Or (haswhile>0) Or (hasuntil>0) then begin
split(retstr[ll],' And ',pars,parscnt);
if parscnt>1 then begin
for ii:=1 to MaxPars do tpars[ii]:='';
for ii:=1 to parscnt do begin
tpars[ii]:=pars[ii];
End;
tparscnt:=parscnt;
if tparscnt>0 then begin
for jj:=1 to tparscnt do begin
split(tpars[jj],' Or ',pars,parscnt);
if parscnt>1 then begin
ii:=pos(' ',pars[1]);
if ii>0 then begin
pars[1]:=Copy(pars[1],1,ii)+'('+Copy(pars[1],ii+1,120);
End Else
Begin
pars[1]:='('+pars[1];
End;
tpars[jj]:=unsplit(pars,') Or (',parscnt);
if hasif>0 then begin
ii:=pos('THEN',upper(tpars[jj]));
if ii>0 then begin
tpars[jj]:=Copy(tpars[jj],1,ii-2)+')'+
Copy(tpars[jj],ii-1,120)
End;
End;
if haswhile>0 then begin
tpars[jj]:=tpars[jj]+')';
End;
if hasuntil>0 then begin
tpars[jj]:=tpars[jj]+')';
End;
End;
End;
End;
parscnt:=tparscnt;
for ii:=1 to parscnt do begin
pars[ii]:=tpars[ii];
End;
ii:=pos(' ',pars[1]);
if ii>0 then begin
pars[1]:=Copy(pars[1],1,ii)+'('+Copy(pars[1],ii+1,120);
End Else
Begin
pars[1]:='('+pars[1];
End;
retstr[ll]:=unsplit(pars,') And (',parscnt);
if hasif>0 then begin
ii:=pos('THEN',upper(retstr[ll]));
if ii>0 then begin
retstr[ll]:=Copy(retstr[ll],1,ii-2)+')'+
Copy(retstr[ll],ii-1,120)
End;
End;
if haswhile>0 then begin
ii:=pos('DO BEGIN',upper(retstr[ll]));
if ii>0 then begin
retstr[ll]:=Copy(retstr[ll],1,ii-2)+')'+
Copy(retstr[ll],ii-1,120)
End;
retstr[ll]:=retstr[ll]+')';
End;
if hasuntil>0 then begin
retstr[ll]:=retstr[ll]+')';
End;
End Else
Begin
split(retstr[ll],' Or ',pars,parscnt);
if parscnt>1 then begin
ii:=pos(' ',pars[1]);
if ii>0 then begin
pars[1]:=Copy(pars[1],1,ii)+'('+Copy(pars[1],ii+1,120);
End Else
Begin
pars[1]:='('+pars[1];
End;
retstr[ll]:=unsplit(pars,') Or (',parscnt);
if hasif>0 then begin
ii:=pos('THEN',upper(retstr[ll]));
if ii>0 then begin
retstr[ll]:=Copy(retstr[ll],1,ii-2)+')'+
Copy(retstr[ll],ii-1,120)
End;
End;
if haswhile>0 then begin
retstr[ll]:=retstr[ll]+')';
End;
if hasuntil>0 then begin
retstr[ll]:=retstr[ll]+')';
End;
End;
End;
End;
{ correct conversion problem with "do while's" }
if pin(' do)',retstr[ll]) then begin
split(retstr[ll],' do)',pars,parscnt);
retstr[ll]:=unsplit(pars,') do',parscnt);
End;
ustr:=upper(retstr[ll]);
delfi2(ll,noext(srcfile),retstr[ll]); { fill Vars.dbf with info }
{ do some "late" simple changes }
for ii:=1 to LateCnt do begin
DoEvents2;
if pin(late[ii,1],retstr[ll]) then begin
split(retstr[ll],late[ii,1],pars,parscnt);
retstr[ll]:=unsplit(pars,late[ii,2],parscnt);
if ii=5 then begin { special case "End Else Begin" }
semistr:='';
End;
End;
End;
{ fix "+;" and ",;" errors on continued lines }
if (ll<lcnt) and (length(retstr[ll])>0) then begin
tt:=Copy(retstr[ll],length(retstr[ll]),1);
if tt='+' then begin
semistr:='';
End;
if tt=',' then begin
semistr:='';
End;
End;
{ no semi's on lines with only a comment }
if pos('{',retstr[ll])=1 then semistr:='';
{ finish afill() conversion, ignore unknown dbf.XX( assign lines }
if pin('YY',retstr[ll]) then begin
ii:=pos(',',retstr[ll]);
if ii>1 then begin
split(retstr[ll],',',pars,parscnt);
retstr[ll]:=unsplit(pars,'[ii]:=',parscnt);
ii:=pos(')',retstr[ll]);
if ii>1 then begin
{ if fill with param has ')', such as space(10), don't
remove trailing ')' }
if pos('))',retstr[ll])=ii then
retstr[ll]:=Copy(retstr[ll],1,ii)
else
retstr[ll]:=Copy(retstr[ll],1,ii-1);
End;
End;
End;
if saveline[ll] then begin
if (caseleft>0) And (indent[ll]>caseleft) then begin
indent[ll]:=indent[ll]-TABWIDTH;
End;
hasif:=pos('IF ',ustr);
if (caseleft>0) And (casecnt>1) And (hasif=1) And
(indent[ll]=caseleft) then begin
putline(space(indent[ll])+'End Else');
End;
if ((hasif=1) or (haswhile>0)) and pin(' $ ',retstr[ll]) then begin
{ do simple conversions of 'aa $ bb' to pin(aa,bb) }
split(retstr[ll],' ',pars,parscnt);
jj:=0;
for ii:=1 to parscnt do begin
if pars[ii]='$' then begin
if pin(' And ',retstr[ll]) or pin(' Or ',ustr) then
pars[ii-1]:='pin'+pars[ii-1]+','+pars[ii+1]
else
pars[ii-1]:='pin('+pars[ii-1]+','+pars[ii+1]+')';
jj:=ii;
break;
end;
end;
if jj>0 then begin
kk:=jj-1;
for ii:=jj+2 to parscnt do begin
pp(kk);
pars[kk]:=pars[ii];
end;
parscnt:=kk;
retstr[ll]:=unsplit(pars,' ',parscnt);
retstr[ll]:=strtran(retstr[ll],') ''',' '')');
end;
end;
{ convert 'go recnum' to 'dbf.go(recnum)' }
if pos('go ',retstr[ll])=1 then begin
retstr[ll]:='dbf.Go('+copy(retstr[ll],4,100)+')';
end;
if (addbegin) And (ll=lcnt) then begin
retstr[ll]:=retstr[ll]+' begin';
End;
if (hasdoproc=1) And (haswhile=0) then begin
if hasdowith then begin
split(retstr[ll],' with ',pars,parscnt);
retstr[ll]:=unsplit(pars,'(',parscnt);
retstr[ll]:=retstr[ll]+')';
End;
End;
ii:=pos('dbUse(',retstr[ll]);
if ii>0 then begin
split(retstr[ll],'''',pars,parscnt);
if parscnt=3 then begin
retstr[ll]:=substr(retstr[ll],1,ii+5)+pars[2]+','+
substr(retstr[ll],ii+6,100);
end;
end;
if empty(retstr[ll]) then
putline(space(indent[ll])+ltrim(acomment[ll]))
else
putline(space(indent[ll])+retstr[ll]+semistr+acomment[ll]);
End;
End;
End;
putline('');
putline('End.');
End;
end;
procedure oDL.delfi2(subnum:integer;themodule,aline:string);
var vlist:array [1..8] of string20;
xtype:array [1..8] of string10;
ii,jj,kk,xcnt:integer;
ustr,tt,cn,vn:string135;
wasinarr:boolean;
begin
{ look for vars, fields, procedure and function declarations }
vlist[1]:='LOCAL ';
xtype[1]:='L';
vlist[2]:='PUBLIC ';
xtype[2]:='P';
vlist[3]:='PRIVATE ';
xtype[3]:='R';
vlist[4]:='STATIC ';
xtype[4]:='S';
vlist[5]:='FIELDS ';
xtype[5]:='F';
vlist[6]:='PARAM';
xtype[6]:='L';
vlist[7]:='FOR ';
xtype[7]:='4';
vlist[8]:='DECLARE ';
xtype[8]:='R';
xcnt:=8;
ustr:=upper(aline);
if empty(curfunc) then begin
curfunc:=themodule;
End;
kk:=pos('PROC ',ustr);
if kk>0 then begin
tt:=ltrim(Copy(aline,kk+5,100));
ii:=pos('(',tt);
if ii>0 then begin
tt:=upper(Copy(tt,1,ii-1));
End;
curfunc:=upper(tt);
End Else
Begin
jj:=pos('PROCEDURE',ustr);
if jj>0 then begin
tt:=ltrim(Copy(aline,jj+10,100));
ii:=pos('(',tt);
if ii>0 then begin
tt:=upper(Copy(tt,1,ii-1));
End;
curfunc:=upper(tt);
End;
End;
kk:=pos('FUNC ',ustr);
if kk>0 then begin
tt:=ltrim(Copy(aline,kk+5,100));
ii:=pos('(',tt);
if ii>0 then begin
tt:=upper(Copy(tt,1,ii-1));
End;
curfunc:=upper(tt);
End Else
Begin
jj:=pos('FUNCTION',ustr);
if jj>0 then begin
tt:=ltrim(Copy(aline,jj+9,100));
ii:=pos('(',tt);
if ii>0 then begin
tt:=upper(Copy(tt,1,ii-1));
End;
curfunc:=upper(tt);
End;
End;
wasinarr:=False;
cn:=padr(upper(curfunc),15);
for ii:=1 to xcnt do begin
DoEvents2;
kk:=pos(vlist[ii],ustr);
if kk=1 then begin
wasinarr:=True;
{ saveline[subnum]=.f.
disgard var declaration lines after processing }
kk:=pos(' ',aline);
if kk>0 then begin
aline:=Copy(aline,kk+1,100);
End;
split(aline,',',pars,parscnt);
{ check for var array declaration of form aa[5,6] }
if parscnt>1 then begin
for jj:=1 to parscnt-1 do begin
if (pin('[',pars[jj])) And (not pin(']',pars[jj+1])) then begin
pars[jj]:=pars[jj]+','+pars[jj+1];
pars[jj+1]:='';
End;
End;
End;
for jj:=1 to parscnt do begin
kk:=pos('=',pars[jj]);
if kk>1 then begin
pars[jj]:=Copy(pars[jj],1,kk-1);
End;
savevar(themodule,cn,pars[jj],xtype[ii],' ',' ');
End;
End;
End;
if Not wasinarr then begin
{ check vars in assignments, field replacements }
ii:=pos('=',aline);
if ii>0 then begin
tt:=Copy(aline,1,ii-1);
if pin('->',tt) then begin
{ field assignment }
split(tt,'->',pars,parscnt);
savevar(themodule,cn,pars[2],'E',pars[1],' ');
End Else
Begin
{ assign using ":=" }
savevar(themodule,cn,tt,'=',' ',' ');
End;
End Else
Begin
ii:=pos('REPL ',ustr);
jj:=pos('REPLACE ',ustr);
if (ii=1) Or (jj=1) then begin
split(aline,' ',pars,parscnt);
tt:=pars[2];
if pin('->',tt) then begin
{ field assignment }
split(tt,'->',pars,parscnt);
savevar(themodule,cn,pars[2],'E',pars[1],' ');
End Else
Begin
savevar(themodule,cn,ltrim(pars[2]),'E',' ',' ');
End;
End;
End;
End;
end;
procedure oDL.savevar(mn,cn,vn,xn,fn,dn:string);
var tn:string20;
begin
tn:=padr(upper(ltrim(vn)),15);
{ dbSelect(vars);
if Not dbf.Seek(tn+cn) then begin
vars.append;
vars.ss('prgname',mn);
vars.ss('funcname',cn);
vars.ss('uppername',tn);
vars.ss('actname',ltrim(vn));
vars.ss('src',xn);
vars.ss('fromdbf',upper(fn));
vars.ss('dbfpath',upper(dn));
End; }
end;
function oDL.mdxconv:boolean;
var ii,jj,kk:integer;
begin
mxronly:=false; { only do mxr() conversion, no other syntax changes }
usemxr:=true; { switch @ commands to use printing subsystem, mxr() }
if (not pin('PRG',srcfile)) then begin
srcfile:=trim(noext(srcfile))+'.PRG';
End;
errfile:=noext(srcfile)+'.FIX'; { errors output file }
parscnt:=0;
for ii:=1 to MaxPars do pars[ii]:='';
{ pass one }
chgcnt:=0; { keep track of number of lines actually changed }
valchk:=False; { during pass 1, check for any "valids", prepend lines to file }
hadsemi:=False; { check for lines with errors that span more than 1 line }
ii7:=0;
ii8:=0;
ii9:=0;
ii10:=0;
for ii:=1 to MAXCHK do begin
for jj:=1 to 2 do simple[ii][jj]:=' ';
for jj:=1 to 2 do late[ii][jj]:=' ';
for jj:=1 to 2 do cmplx[ii][jj]:=' ';
End;
initarrs(True);
{ pass 1, may add lines to the file }
curline:=1;
cnvrt(1);
inlines.assign(outlines);
outlines.clear;
{ pass 2, convert code }
curline:=1;
cnvrt(2);
{ DeleteFile(temp2);
DeleteFile(temp3); }
end;
procedure oDL.cnvrt(passlev:integer);
var ii:integer;
begin
retstr:='';
indent:=0;
acom:='';
inproc:=True;
endline:=False;
tst:='';
{ init buffer first }
{ start processing }
{ find statics, locals, publics, privates, do mxr() conv. }
if passlev=1 then begin
linecnt:=0;
curline:=1;
db2dl.progress.caption:='Phase 1';
While True do begin
DoEvents2;
if getline(tst) then begin
pp(curline);
wasmxr:=False;
orgtst:=tst; { in case we have to undo an mxr() conversion }
chkline(wasmxr);
afterchk:=tst;
{ convert @ say's to mxr() in first pass }
if wasmxr then begin
mxrcnt:=0;
for ii:=1 to 10 do mxlist[ii]:=' ';
for ii:=1 to 10 do mxorg[ii]:=' ';
While True do begin
DoEvents2;
if getline(tst) then begin
pp(curline);
if (curline mod 100)=0 then
db2dl.progress.caption:='Phase 1, Line '+str(curline,5,0);
org2:=tst;
indent:=0;
acom:='';
threepcs(indent,org2,acom);
if (Copy(org2,length(org2),1)=';') And (mxrcnt<10) then begin
pp(mxrcnt);
mxlist[mxrcnt]:=org2;
mxorg[mxrcnt]:=tst;
End Else
Begin
pp(mxrcnt);
mxlist[mxrcnt]:=upper(org2); { text only }
mxorg[mxrcnt]:=tst; { full original line }
break;
End;
end else break;
End;
if (mxrcnt>0) then begin
hadget:=0;
for ii:=1 to mxrcnt do begin
if pin('GET',mxlist[ii]) then begin
hadget:=ii;
break;
End;
End;
if hadget>0 then begin
{ was "get" on one of the lines }
{ write "@ say" line #1, then the rest, no changes }
putline(orgtst);
for ii:=1 to mxrcnt do begin
putline(mxorg[ii]);
End;
End Else
Begin
{ no "get", do mxr() conversion on multi-line text }
{ write "@ say" line #1, then the rest, no changes }
putline(afterchk);
if mxrcnt>1 then begin
for ii:=1 to mxrcnt-1 do begin
putline(mxorg[ii]);
End;
End;
{ parse last line, add ")" to end }
indent:=0;
acom:='';
org2:=mxorg[mxrcnt];
threepcs(indent,org2,acom);
org2:=org2+')';
putline(space(indent)+org2+acom);
End;
End;
end;
End else break; { no more lines }
End;
End;
if passlev=2 then begin { convert code }
curline:=1;
linecnt:=0;
db2dl.progress.caption:='Phase 2';
While True do begin
DoEvents2;
if getline(tst) then begin
pp(curline);
if (curline mod 100)=0 then
db2dl.progress.caption:='Phase 2, Line '+str(curline,5,0);
fixline;
end else break;
End;
End;
end;
procedure oDL.convmxr(var astr:string;var waschg:boolean);
var pc1,pc2,tt2,tt3:string135;
jj,mm,kk,ii:integer;
begin
if usemxr then begin
{ convert @ ?,? say ? to mxr(?,?,?) }
pc1:=trim(upper(astr));
hadsemi:=(Copy(astr,length(astr),1)=';');
if (Copy(pc1,1,1)='@') And (Not (pin(' GET ',pc1))) And
(pin('SAY',pc1)) then begin
{ check for @3,5 style, convert to @ 3,5 }
if Copy(pc1,2,1)<>' ' then begin
astr:='@ '+Copy(astr,2,120);
End;
{ check for say" style, convert to say " }
jj:=pos(' say"',astr);
if jj>0 then begin
astr:=Copy(astr,1,jj+3)+' '+Copy(astr,jj+4,120);
End;
jj:=pos(' say ',astr);
kk:=pos(', ',astr);
if (kk>0) And (kk<jj) then begin
astr:=stuff(astr,kk,2,',');
End;
jj:=pos(' say ',astr);
kk:=pos(' ',astr);
if (kk>0) And (kk<jj) then begin
astr:=stuff(astr,kk,2,' ');
End;
split(astr,' ',pars,parscnt);
pc1:='';
jj:=pos(' say ',astr);
kk:=pos(' picture',astr);
mm:=length(' picture');
if kk=0 then begin
kk:=pos(' pict',astr);
mm:=length(' pict');
End;
tt3:=' ';
if kk=0 then begin
kk:=length(astr);
tt2:=Copy(astr,jj+5,kk-(jj+5)+1);
End Else
Begin
tt2:=Copy(astr,jj+5,kk-(jj+5)+1);
tt3:=trim(Copy(astr,kk+mm,length(astr)));
End;
for ii:=1 to parscnt do begin
pc2:=pars[ii];
if Not empty(pars[ii]) then begin
if pc2='@' then begin
pc2:='prn.p(';
End Else
if pc2='say' then begin
pc2:=',';
if Not empty(tt3) then begin
for jj:=ii+1 to parscnt do begin
pars[jj]:=' ';
End;
pars[ii+1]:='transform('+trim(tt2)+','+ltrim(trim(tt3))+')';
End Else Begin
for jj:=ii+1 to parscnt do begin
pars[jj]:=' ';
End;
pars[ii+1]:=trim(tt2);
End;
End;
if ii<parscnt then begin
pc1:=pc1+pc2;
End;
End;
End;
if Not hadsemi then begin
{ if not a continued line, then the conversion is complete }
{ leave waschg .f., so no further mxr() conversion will be done }
pc1:=pc1+trim(pc2)+')';
End Else
Begin
pc1:=pc1+trim(pc2);
waschg:=True;
End;
astr:=pc1;
End;
End;
end;
function oDL.getline(var aStr:string):boolean;
begin
if linecnt<inlines.count then begin
aStr:=inlines[linecnt];
pp(linecnt);
result:=true;
end else result:=false;
end;
procedure oDL.putline(aStr:string);
begin
outlines.add(aStr);
end;
function oDL.chkline(wasmxr:boolean):boolean;
var ii:integer;
tt:string135;
begin
retstr:='';
acom:='';
indent:=0;
line1:='';
line2:='';
for ii:=1 to 50 do equl[ii]:='';
acnt:=0;
if length(tst)>0 then begin
retstr:=tst;
threepcs(indent,retstr,acom);
convmxr(retstr,wasmxr);
tst:=retstr;
line1:=tst;
tt:=upper(tst);
if pin('PUBLIC',tt) then begin
nuline(tst,line1,line2,equl,acnt);
valchk:=True; { force prefix of defines to file }
End Else
if pin('PRIVATE',tt) then begin
nuline(tst,line1,line2,equl,acnt);
End Else
if pin('LOCAL',tt) then begin
nuline(tst,line1,line2,equl,acnt);
End;
End;
if Not wasmxr then begin { only save string if not an mxr() conversion }
putline(space(indent)+line1+acom);
if Not empty(line2) then begin
putline(space(indent)+line2);
End;
if acnt>0 then begin
for ii:=1 to acnt do begin
putline(space(indent)+equl[ii]);
End;
End;
End;
Result:=True;
end;
function oDL.fixline:boolean;
var tt2,tt3,org2:string135;
jj,ii,kk,mm:integer;
bytag:boolean;
begin
retstr:='';
indent:=0;
acom:='';
if length(tst)>0 then begin
orgstr:=tst;
retstr:=orgstr;
threepcs(indent,retstr,acom);
org2:=retstr;
if Not mxronly then begin
{ ++ option }
if (pin('++',retstr)) And (Not (pin('+++',retstr))) then begin
ii:=pos('++',retstr);
if ii=1 then begin
pc1:=Copy(retstr,ii+2,12);
retstr:=pc1+'='+ltrim(pc1)+'+1';
End;
if ii=length(retstr)-1 then begin
pc1:=Copy(retstr,1,ii-1);
retstr:=pc1+'='+ltrim(pc1)+'+1';
End;
End;
{ -- option }
if (pin('--',retstr)) And (Not (pin('---',retstr))) then begin
ii:=pos('--',retstr);
if ii=1 then begin
pc1:=Copy(retstr,ii+2,12);
retstr:=pc1+'='+ltrim(pc1)+'-1';
End;
if ii=length(retstr)-1 then begin
pc1:=Copy(retstr,1,ii-1);
retstr:=pc1+'='+ltrim(pc1)+'-1';
End;
End;
{ += option }
if pin('+=',retstr) then begin
split(retstr,'+',pars,parscnt);
pc1:=pars[1];
split(retstr,'=',pars,parscnt);
pc2:=pars[2];
retstr:=pc1+'='+ltrim(pc1)+'+('+pc2+')';
End;
{ -= option }
if pin('-=',retstr) then begin
split(retstr,'-',pars,parscnt);
pc1:=pars[1];
split(retstr,'=',pars,parscnt);
pc2:=pars[2];
retstr:=pc1+'='+ltrim(pc1)+'-('+pc2+')';
End;
{ *= option }
if pin('*=',retstr) then begin
split(retstr,'*',pars,parscnt);
pc1:=pars[1];
split(retstr,'=',pars,parscnt);
pc2:=pars[2];
retstr:=pc1+'='+ltrim(pc1)+'*('+pc2+')';
End;
{ /= option }
if pin('/=',retstr) then begin
split(retstr,'/',pars,parscnt);
pc1:=pars[1];
split(retstr,'=',pars,parscnt);
pc2:=pars[2];
retstr:=pc1+'='+ltrim(pc1)+'/('+pc2+')';
End;
End;
for ii:=1 to SimpleCnt do begin
DoEvents2;
if Not empty(simple[ii,1]) then begin
if (ii=ii7) And (pin('pict',retstr)) then begin
continue;
End;
if (ii=ii8) And (pin('mxprow',retstr)) then begin
continue;
End;
if (ii=ii9) And (pin('mxpcol',retstr)) then begin
continue;
End;
if (ii=ii10) And (pin('mxsetprc',retstr)) then begin
continue;
End;
if (ii=13) And (pin('REQ',retstr)) then begin
continue;
End;
jj:=pos(simple[ii,1],retstr);
if (ii=ii7) And (jj>0) And (mxronly) then begin
continue;
End;
While jj>0 do begin
DoEvents2;
pc1:='';
pc2:='';
if jj>1 then begin
pc1:=Copy(retstr,1,jj-1);
if length(retstr)>(jj-1+length(simple[ii,1])) then begin
pc2:=Copy(retstr,jj+length(simple[ii,1]),120);
End;
End Else
Begin
pc2:=Copy(retstr,length(simple[ii,1])+1,120);
End;
retstr:=pc1+simple[ii,2]+pc2;
jj:=pos(simple[ii,1],retstr);
{ if we know this can only occur once, just exit }
if (ii=ii8) And (pin('mxprow',retstr)) then begin
break;
End;
if (ii=ii9) And (pin('mxpcol',retstr)) then begin
break;
End;
if (ii=ii10) And (pin('mxsetprc',retstr)) then begin
break;
End;
if (ii=13) And (pin('REQ',retstr)) then begin
break;
End;
End;
End;
End;
if Not mxronly then begin
if pin('SET ORDER',upper(retstr)) then begin
bytag:=pin(' TAG',upper(retstr));
split(retstr,' ',pars,parscnt);
if not bytag then begin
if parscnt=3 then begin
retstr:='mxsetorder(0)';
End Else
if parscnt=4 then begin
retstr:='mxsetorder('+pars[4]+')';
End Else
if parscnt=5 then begin
if pin('"',pars[5]) or pin('''',pars[5]) then begin
retstr:='mxtagorder('''+pars[5]+''')';
End Else
Begin
retstr:='mxsetorder(0)';
End;
End;
end else begin
if parscnt=5 then begin
if pin('"',pars[5]) or pin('''',pars[5]) then begin
retstr:='mxtagorder('+pars[5]+')';
End Else Begin
retstr:='mxtagorder('''+pars[5]+''')';
End;
End else retstr:='mxtagorder('''')';
end;
End;
jj:=pos('SEEK ',upper(retstr));
if jj=1 then begin
retstr:='mxseek('+substr(retstr,jj+5,120)+')';
End;
{ now for more complicated stuff }
if (pin(':=',retstr)) and (pin('->',retstr)) then begin
split(retstr,':',pars,parscnt);
pc1:=pars[1];
orgstr:=ltrim(pc1);
ii:=pos('=',retstr);
pc2:=ltrim(Copy(retstr,ii+1,120));
retstr:='replace '+orgstr+' with '+pc2
End;
if pin('(',retstr) then begin
for jj:=1 to CmplxCnt do begin
DoEvents2;
if Not empty(cmplx[jj,1]) then begin
split(retstr,' ',pars,parscnt);
retstr:='';
xarr.clear;
for ii:=1 to parscnt do begin
xarr.add(pars[ii]);
End;
xcnt:=parscnt;
for ii:=1 to xcnt do begin
if pin(cmplx[jj,1],xarr[ii-1]) then begin
split(xarr[ii-1],'-',pars,parscnt);
pc1:=pars[1];
if pin('()',xarr[ii-1]) then begin { no param }
if jj=9 then begin
{ for recno() }
split(xarr[ii-1],'(',pars,parscnt);
xarr[ii-1]:=pars[3];
split(xarr[ii-1],')',pars,parscnt);
pc2:=pars[1];
kk:=pos('=',pc1);
if kk>0 then begin
xarr[ii-1]:=Copy(pc1,1,kk)+cmplx[jj,2]+'('''+
Copy(pc1,kk+1,12)+''')'
End Else
Begin
xarr[ii-1]:=cmplx[jj,2]+'()';
End;
End Else
Begin
xarr[ii-1]:=cmplx[jj,2]+'()';
End;
End Else
Begin { has a param }
{ split(xarr[ii-1],"(",pars,parscnt) }
{ xarr[ii-1]=pars[3] }
{ split(xarr[ii-1],")",pars,parscnt) }
kk:=pos(cmplx[jj,1],xarr[ii-1])+length(cmplx[jj,1])+1;
pc2:=Copy(xarr[ii-1],kk,120);
pc2:=Copy(pc2,1,length(pc2)-2); { knock off last )) }
xarr[ii-1]:=cmplx[jj,2]+'('+pc2+')';
End;
End;
if ii<xcnt then begin
retstr:=retstr+xarr[ii-1]+' ';
End Else
Begin
retstr:=retstr+xarr[ii-1];
End;
End;
End;
End;
End;
End;
kk:=0;
for ii:=1 to LateCnt do begin
DoEvents2;
if Not empty(late[ii,1]) then begin
if (ii=7) And (pin('pict',retstr)) then begin
continue;
End;
if (ii=10) And (pin('mxbof',retstr)) then begin
continue;
End;
jj:=pos(late[ii,1],retstr);
While (jj>0) And (jj>kk) do begin
DoEvents2;
pc1:='';
pc2:='';
if jj>1 then begin
pc1:=Copy(retstr,1,jj-1);
if length(retstr)>(jj-1+length(late[ii,1])) then begin
pc2:=Copy(retstr,jj+length(late[ii,1]),120);
End;
End Else
Begin
pc2:=Copy(retstr,length(late[ii,1])+1,120);
End;
retstr:=pc1+late[ii,2]+pc2;
kk:=jj+length(late[ii,2]);
if ii=11 then begin { special case for mxskip() }
if pin(''''',)',retstr) then begin
retstr:=pc1+'mxskip';
kk:=jj+length(late[ii,2]);
End;
End;
jj:=pos(late[ii,1],retstr);
End;
End;
End;
pc1:=ltrim(upper(retstr));
if Not mxronly then begin
if pin('PROCEDU',pc1) then begin
inproc:=True;
End;
if pin('FUNCTIO',pc1) then begin
inproc:=False;
End;
End;
{ finally, check for hand changes and some final automatic }
{ changes }
errmess:=' ';
if 'DELETE'=trim(upper(retstr)) then begin
retstr:='mxdelete()';
End;
if 'RECALL'=trim(upper(retstr)) then begin
retstr:='mxrecall()';
End;
{ convert "set message to ??" to mxppmes=?? }
if pin('SET MESS',upper(retstr)) then begin
split(retstr,' ',pars,parscnt);
if parscnt=4 then begin
retstr:='mxppmes='+pars[4]+' '+comstr+
' ''set message to'' conversion';
End;
End;
pc1:=ltrim(upper(retstr));
{ if last line had a semi-colon and an error, show next line }
retstr:=trim(retstr);
{ scan for up to three continued lines }
if Copy(retstr,length(retstr)-1,2)=';)' then begin
retstr:=Copy(retstr,1,length(retstr)-1);
endline:=True;
End Else
Begin
if endline then begin
retstr:=retstr+')';
if Copy(retstr,length(retstr)-1,2)=';)' then begin
retstr:=Copy(retstr,1,length(retstr)-1);
endline:=True;
End Else
Begin
endline:=False;
End;
End;
End;
if Copy(retstr,length(retstr),1)=';' then begin
if Not empty(errmess) then begin
hadsemi:=True;
End;
End Else
Begin
hadsemi:=False;
End;
if org2<>retstr then begin
pp(chgcnt);
End;
if empty(retstr) then putline(space(indent)+acom)
else putline(space(indent)+retstr+' '+acom);
End Else
Begin
putline('');
End;
Result:=True;
end;
procedure oDL.nuline(orgstr,line1,line2:string;
var equallist:array of string135;var ecnt:integer);
var jj,pcnt,ii,rcnt,kk,zz:integer;
heading,orgvars,declist,tt:string135;
assign:boolean;
begin
tt:=upper(orgstr);
assign:=False;
if pin('LOCAL',tt) then begin
assign:=True;
End Else
if pin('PRIVATE',tt) then begin
assign:=True;
End Else
if pin('PUBLIC',tt) then begin
assign:=True;
End Else
if pin('STATIC',tt) then begin
assign:=True;
End;
if assign then begin
jj:=pos(' ',orgstr);
if jj>0 then begin
{ check for assignment in declaration line }
{ Clipper allows this using ":=", DBW doesn't }
if pin('=',orgstr) then begin { convert ":=" to "=" }
for ii:=1 to 30 do begin
zz:=pos('=',orgstr);
if zz>0 then begin
orgstr:=stuff(orgstr,zz,2,'=');
End Else
Begin
break;
End;
End;
End;
heading:=Copy(orgstr,1,jj-1);
orgvars:=Copy(orgstr,jj+1,120);
declist:='';
split(orgvars,',',pars,parscnt);
pcnt:=0;
rcnt:=0;
for ii:=1 to 30 do plist[ii]:='';
for ii:=1 to 30 do rlist[ii]:='';
for kk:=1 to parscnt do begin
if Not empty(pars[kk]) then begin
if (not pin('[',pars[kk])) then begin
{ check for assignment in declaration line }
zz:=pos('=',pars[kk]);
if zz=0 then begin
pp(rcnt);
rlist[rcnt]:=pars[kk];
End Else
Begin
pp(ecnt);
equallist[ecnt-1]:=pars[kk];
if pin('{}',equallist[ecnt-1]) then begin
pp(pcnt);
plist[pcnt]:=Copy(pars[kk],1,zz-1)+'[0]';
equallist[ecnt-1]:='';
ecnt:=ecnt-1;
End Else
Begin
pp(rcnt);
rlist[rcnt]:=Copy(pars[kk],1,zz-1);
End;
End;
End Else
Begin
pp(pcnt);
plist[pcnt]:=pars[kk];
if (not pin(']',pars[kk])) then begin
plist[pcnt]:=pars[kk]+','+pars[kk+1];
pars[kk+1]:='';
End;
End;
End;
End;
orgvars:='';
declist:='';
if rcnt>0 then begin
orgvars:=heading+' ';
for kk:=1 to rcnt do begin
orgvars:=orgvars+rlist[kk]+',';
End;
orgvars:=Copy(orgvars,1,length(orgvars)-1);
End;
if pcnt>0 then begin
declist:='declare ';
if (pin('STATIC',upper(heading))) Or (pin('PUBLIC',upper(heading))) then begin
declist:='public ARR ';
End;
for kk:=1 to pcnt do begin
declist:=declist+plist[kk]+',';
End;
declist:=Copy(declist,1,length(declist)-1);
End;
End;
line1:=orgvars;
if pcnt>0 then begin
line2:=declist+' '+comstr+' from '+heading;
End;
End;
end;
procedure oDL.AddSimple(s1,s2:string);
begin
pp(SimpleCnt);
simple[SimpleCnt,1]:=s1;
simple[SimpleCnt,2]:=s2;
end;
procedure oDL.AddLate(s1,s2:string);
begin
pp(LateCnt);
late[LateCnt,1]:=s1;
late[LateCnt,2]:=s2;
end;
procedure oDL.AddCmplx(s1,s2:string);
begin
pp(CmplxCnt);
cmplx[CmplxCnt,1]:=s1;
cmplx[CmplxCnt,2]:=s2;
end;
procedure oDL.AddProc(ftest,a0,a1,a2:string);
begin
pp(ProcCnt);
proctest[ProcCnt]:=ftest;
proc0arg[ProcCnt]:=a0;
proc1arg[ProcCnt]:=a1;
proc2arg[ProcCnt]:=a2;
if empty(a1) then begin
proc1arg[ProcCnt]:=a0;
end;
if empty(a2) then begin
proc0arg[ProcCnt]:=a0;
end;
end;
procedure oDL.initarrs(fordbw:boolean); { INITARRS }
begin
SimpleCnt:=0;
LateCnt:=0;
CmplxCnt:=0;
ProcCnt:=0;
if not fordbw then begin
AddSimple('.t.','True');
AddSimple('.f.','False');
AddSimple('.not.','Not');
AddSimple('.and.','And');
AddSimple('.or.','Or');
AddSimple('/*','{ ');
AddSimple('*/',' }');
AddSimple('endif','End');
AddSimple('do while','While');
AddSimple('"','''');
AddSimple('otherwise','End Else Begin');
AddSimple('delete','dbf.Delete');
AddSimple('return ','Result:=');
AddSimple('return','Exit');
AddSimple('at(','pos(');
AddSimple('date()','xDate');
AddSimple('substr(','Copy(');
AddSimple('exit','break');
AddSimple('loop','continue');
AddSimple('mxr(','prn.p(');
AddSimple('mxrpwid(','prn.ReportWidth(');
AddSimple('mxsetprc(','prn.SetRowCol(');
AddSimple('fcrlf(','prn.CrLf(');
AddSimple('mxreject()','prn.Eject');
AddSimple('mxreject(False)','prn.Eject');
AddSimple('mxpcol()','prn.pCol');
AddSimple('mxprow()','prn.pRow');
AddSimple('mxprset(','prn.PrSetMode(');
AddSimple('useidx(','dbUse(');
AddSimple('enddo','End');
AddSimple('center(','padc(');
AddSimple('len(','length(');
AddSimple('afill(','for ii:=1 to YY do ');
AddSimple('select()','dbf.Select(');
AddSimple('specchars(','prn.SpecChars(');
AddSimple('select (','dbSelectArea(');
AddSimple('linespp','prn.PgLen');
AddSimple('Page','prn.Page');
AddSimple('next','End');
AddSimple('procint(','ProcDbl(');
AddSimple('swait(','OKbox(');
AddSimple('laztray','prn.LazTray');
AddSimple('lazline','prn.LazLine');
AddSimple('lazbox','prn.LazBox');
AddSimple('laztext','prn.LazText');
AddSimple('lazinch','prn.LazInch');
AddSimple('lazspecial','prn.LazSpecial');
AddSimple('go top','dbf.GoTop');
AddSimple('go bottom','dbf.GoBottom');
AddSimple('iif(','iifi('); { convert iif( to iifi( }
{ these lines must come after any changes containing 'line/page' }
AddSimple('line','prn.Line');
AddSimple('page','prn.Page');
AddLate('eof()','dbf.eof');
AddLate('skip','dbf.skip');
AddLate('recno()','dbf.Recno');
AddLate('xaLock(ds, ,','dbf.aLock');
AddLate('uztmpdbf(ds,','uztmpdbf(');
AddLate('(ds,','(');
AddLate('Lock(True)','Lock');
AddLate('()','');
{ define function substitutions
~ after processing, result should have no parameters
case is important when the search pattern is part of the result
pattern, i.e. do not use 'pack' with change to pattern of 'dbpack'
it will go into an infinite loop }
AddProc('mxskip','dbf.Skip~','dbf.Skip~','dbf.Skip2');
AddProc('mxappend','dbf.Append~','dbf.Append~','dbf.Append~');
AddProc('mxbof','dbf.Bof~','dbf.Bof~','dbf.Bof~');
AddProc('mxbottom','dbf.GoBottom~','dbf.GoBottom~','b.GoBottom~');
AddProc('mxclose','dbf.Close~','dbf.Close~','dbf.Close~');
AddProc('mxdbdel','dbf.Delete~','dbf.Delete~','dbf.Delete~');
AddProc('mxdeld','dbf.Deleted~','dbf.Deleted~','dbf.Deleted~');
AddProc('mxeof','dbf.Eof~','dbf.Eof~','dbf.Eof~');
AddProc('mxgo','dbf.Go','dbf.Go','dbf.Go');
AddProc('mxgoto','dbf.Go','dbf.Go','dbf.Go');
AddProc('mxlock','dbf.Lock~','dbf.Lock~','dbf.Lock~');
AddProc('mxalock','dbf.aLock~','dbf.aLock~','dbf.aLock~');
AddProc('mxrecno','dbf.RecNo~','dbf.RecNo~','dbf.RecNo~');
AddProc('mxseek','dbf.Seek','dbf.Seek','dbf.Seek');
AddProc('mxsetorder','dbf.SetOrder','dbf.SetOrder','dbf.SetOrder');
AddProc('mxtagorder','dbf.TagOrder','dbf.TagOrder','dbf.TagOrder');
AddProc('mxtop','dbf.Top~','dbf.Top~','dbf.Top~');
AddProc('mxunlock','dbf.unLock~','dbf.unLock~','dbf.unLock~');
AddProc('lastrec','dbf.LastRec~','dbf.LastRec~','dbf.LastRec~');
AddProc('pack','dbf.Pack~','dbf.Pack~','dbf.Pack~');
AddProc('reccount','dbf.RecCount~','dbf.RecCount~','dbf.RecCount~');
AddProc('mxrecall','dbf.Recall~','dbf.Recall~','dbf.Recall~');
AddProc('zap','dbf.Zap~','dbf.Zap~','dbf.Zap~');
AddProc('clozdbf','dbClose(ZZ)~','dbClose(ZZ)~','dbClose(ZZ)~');
AddProc('clozall','dbf.CloseAll~','dbf.CloseAll~','dbf.CloseAll~');
AddProc('loadtags','dbf.LoadTags~','dbf.LoadTags~','dbf.LoadTags~');
AddProc('devtopr','prn.StartDoc(for8by11,forText,'''')~',
'prn.StartDoc(for8by11,forText,'''')~',
'prn.StartDoc(for8by11,forText,'''')~');
AddProc('devtoscr','prn.StopDoc~','prn.StopDoc~','prn.StopDoc~');
end else begin
{ simple substitions, done first }
AddSimple('!=','<>');
AddSimple('==','=');
AddSimple('clear screen','clrscrn()');
AddSimple('close all','clozall()');
AddSimple('][',',');
AddSimple('!','.not. ');
ii7:=SimpleCnt;
AddSimple('prow','mxprow');
ii8:=SimpleCnt;
AddSimple('pcol','mxpcol');
ii9:=SimpleCnt;
AddSimple('setprc','mxsetprc');
ii10:=SimpleCnt;
AddSimple('feject','mxreject');
AddSimple('achoice','mxchoice');
{ simple substitions, done last }
{ unlockit first because lockit is subpart }
AddLate('unlockit','mxunlock');
AddLate('lockit','mxlock');
AddLate('dbappend','mxappend');
AddLate('append blank','mxappend()');
AddLate('dbseek(','mxseek(');
AddLate('dbsetorder(','mxsetorder(');
AddLate('mxlock(.','mxlock(.');
AddLate('dbdelete(','mxdbdel(');
AddLate('deleted(','mxdeld(');
AddLate('bof(','mxbof(');
{ see special case below, search for mxskip }
AddLate('dbskip(','mxskip('',');
AddLate('dbclosearea(','mxclose(');
AddLate('dbgoto(','mxgoto(');
AddLate('fieldname(','field(');
AddLate('fcount(','mxfcount(');
AddLate('dbrecall(','mxrecall(');
{ complex substitions of form emp->(dbappend()) }
AddCmplx('unlockit','mxunlock');
AddCmplx('lockit','mxlock');
AddCmplx('dbappend','mxappend');
AddCmplx('dbseek','mxseek');
AddCmplx('clozdbf','mxclose');
AddCmplx('dbsetorder','mxsetorder');
AddCmplx('eof','mxeof');
AddCmplx('dbskip','mxskip');
AddCmplx('recno','mxrecno');
AddCmplx('dbgobottom','mxbottom');
AddCmplx('dbgotop','mxtop');
AddCmplx('dbgoto','mxgoto');
AddCmplx('dbdelete','mxdbdel');
AddCmplx('deleted','mxdeld');
AddCmplx('bof','mxbof');
AddCmplx('rlock','mxlock');
AddCmplx('dbclosearea','mxclose');
end;
end;
procedure oDL.threepcs(var tindent:integer;
var tretstr,tacomment:string);
var tt,nust,tt2:string;
jj,ii,offset:integer;
begin
tab:=chr(9);
nust:='';
if pin(tab,tretstr) then begin
for ii:=1 to length(tretstr) do begin
tt2:=Copy(tretstr,ii,1);
if ord(tt2[1])=9 then begin { tab key }
tt2:=space(TABWIDTH);
End;
nust:=nust+tt2;
End;
End Else
Begin
nust:=tretstr;
End;
tretstr:=nust;
tt:=ltrim(tretstr);
tindent:=length(tretstr)-length(tt);
tretstr:=tt;
jj:=pos('//',tretstr);
offset:=2;
if jj>0 then begin
tretstr:=Copy(tretstr,1,jj-1)+' '+comstr+Copy(tretstr,jj+2,120);
end else begin
jj:=pos('&&',tretstr);
if jj>0 then begin
tretstr:=Copy(tretstr,1,jj-1)+' '+comstr+Copy(tretstr,jj+2,120);
end else begin
jj:=pos('*',tretstr);
if jj=1 then begin
tretstr:=Copy(tretstr,1,jj-1)+' '+comstr+Copy(tretstr,jj+1,120);
offset:=1;
end;
end;
End;
{ save the comment and clear it }
tacomment:='';
ii:=pos(comstr,tretstr);
if ii=1 then begin
tacomment:=tretstr;
tretstr:='';
End;
if ii>1 then begin
tacomment:=' '+comstr+Copy(tretstr,ii+offset,120);
tretstr:=trim(Copy(tretstr,1,ii-1));
End;
tretstr:=trim(tretstr);
end;
procedure oDL.loadflds(dpath:string);
var dbfcnt,ii,jj:integer;
dbflist:tstringlist;
dbf:oDB;
flds:DBFstruct;
tt:string;
begin
dbflist:=tstringlist.create;
flds:=DBFstruct.create;
LoadFileList(dpath,'*.DBF',dbflist);
dbf:=nil;
dbfcnt:=dbflist.count;
if dbfcnt>0 then begin
for ii:=0 to dbfcnt-1 do begin
DoEvents2;
tt:=dpath+'\'+noext(dbflist[ii]);
dbUse(dbf,tt);
dbf.GetDBFStruct(flds);
dbClose(dbf);
if flds.fcount>0 then begin
for jj:=1 to flds.fcount do begin
fields.append;
with flds do begin
fields.ss('fld',upper(fname[jj]));
fields.ss('ftype',upper(ftype[jj]));
fields.ii('flen',fwidth[jj]);
fields.ii('fdec',fdecs[jj]);
fields.ss('fromdbf',upper(noext(dbflist[ii])));
fields.ss('path',upper(dpath));
end;
End;
End;
End;
End;
dbflist.free;
flds.free;
end;
function oDL.fldconv(orgstr:string):string;
var ustr,res,tt,tt2,fldname,aliasname,repval:string135;
tt3,ufld,ualias:string135;
fndfld:boolean;
parscnt2,withat,ii,jj,kk,mm:integer;
pars2:array [1..MaxPars] of string135;
begin
ustr:=upper(orgstr);
res:=orgstr;
fldname:='';
aliasname:='';
repval:='';
{ dBase style }
if (pin('REPL ',ustr)) Or (pin('REPLACE ',ustr)) then begin
split(ustr,' ',pars2,parscnt2);
withat:=0;
for ii:=1 to parscnt2 do begin
if pars2[ii]='WITH' then begin
withat:=ii;
break;
End;
End;
{ split original string before building subsections }
split(orgstr,' ',pars2,parscnt2);
if withat>0 then begin
tt:='';
tt2:='';
for ii:=2 to withat-1 do begin
tt:=tt+pars2[ii];
End;
for ii:=withat+1 to parscnt2 do begin
if ii<parscnt2 then begin
repval:=repval+pars2[ii]+' ';
End Else
Begin
repval:=repval+pars2[ii];
End;
End;
repval:=fldconv(repval);
{ contains stuff between "replace" and "with" }
if pin('->',tt) then begin
split(tt,'->',pars2,parscnt2);
aliasname:=pars2[1];
fldname:=pars2[2];
End Else
Begin
aliasname:='';
fldname:=tt;
End;
End;
End;
if empty(fldname) then begin
{ look for Clipper style replacement: cust->cust_no:="3533" }
ii:=pos(':=',orgstr);
jj:=pos('->',orgstr);
if (ii>0) And (jj>0) And (jj<ii) then begin
split(orgstr,':=',pars2,parscnt2);
repval:=fldconv(pars2[2]);
tt:=Copy(orgstr,1,ii-1);
if pin('->',tt) then begin { contains stuff between beginning of line and ":=" }
split(tt,'->',pars2,parscnt2);
aliasname:=pars2[1];
fldname:=pars2[2];
End Else
Begin
aliasname:='';
fldname:=tt;
End;
End;
End;
if empty(fldname) then begin { look for retrieval of field info rather than assignment }
split(orgstr,'->',pars2,parscnt2);
if parscnt2>1 then begin { at least one field reference }
{ change "->" to "~~" to avoid infinite loop }
orgstr:=unsplit(pars2,'~~',parscnt2);
mm:=pos('~~',orgstr);
jj:=0;
kk:=0;
{ find the beginning and end of field reference }
while mm>0 do begin
DoEvents2;
for ii:=mm-1 downto 1 do begin
tt:=Copy(orgstr,ii,1);
if pin(tt,CHARLIST) then begin
jj:=ii;
if pin(tt,DELIMLIST) then begin
jj:=ii+1;
break;
End;
End Else
Begin
break;
End;
End;
for ii:=mm+2 to length(orgstr) do begin
tt:=Copy(orgstr,ii,1);
if pin(tt,CHARLIST) then begin
kk:=ii;
if pin(tt,DELIMLIST) then begin
kk:=ii-1;
break;
End;
End Else
Begin
break;
End;
End;
{ found start and finish? }
if (jj>0) And (kk>0) then begin
tt:='';
if jj>1 then begin
tt:=Copy(orgstr,1,jj-1); { upto field info }
End;
tt2:='';
if jj>1 then begin
tt2:=Copy(orgstr,kk+1,100); { after field info }
End;
tt3:=Copy(orgstr,jj,kk-jj+1); { field reference }
split(tt3,'~~',pars2,parscnt2);
aliasname:=pars2[1];
fldname:=pars2[2];
ufld:=upper(padr(fldname,10));
ualias:=upper(padr(aliasname,8));
fndfld:=False;
if fields.Seek(ufld+ualias) then begin
fndfld:=True;
End Else
Begin
if fields.Seek(ufld) then begin
fndfld:=True;
End;
End;
if fndfld then begin
if fields.s('ftype')='N' then begin
if fields.i('flen')<7 then begin
if fields.i('fdec')>0 then
tt3:=aliasname+'.f('''+fldname+''')'
else
tt3:=aliasname+'.f('''+fldname+''')'; { S/B .i( }
end else
tt3:=aliasname+'.f('''+fldname+''')';
End Else
if fields.s('ftype')='L' then begin
tt3:=aliasname+'.b('''+fldname+''')';
End Else
if fields.s('ftype')='D' then begin
tt3:=aliasname+'.d('''+fldname+''')';
End Else
if fields.s('ftype')='C' then begin
tt3:=aliasname+'.s('''+fldname+''')';
End Else Begin
tt3:=aliasname+'.X('''+fldname+''')';
End;
End Else
Begin
tt3:=aliasname+'.X('''+fldname+''')';
End;
{ tie back together }
End Else
Begin
tt:=Copy(orgstr,1,mm-1); { upto field info }
tt2:=Copy(orgstr,mm+2,140); { after field info }
tt3:='';
End;
orgstr:=tt+tt3+tt2;
mm:=pos('~~',orgstr);
End;
res:=orgstr;
End;
End Else
Begin
tt:=upper(padr(fldname,10));
tt2:=upper(padr(aliasname,8));
if empty(tt2) then begin
tt2:=''; { shorten search string to just "tt" }
End;
{ if it doesn't find the field, it returns "dbX()" as the function }
{ where "X" will have to be changed to the correct method name by hand }
fndfld:=False;
if fields.Seek(tt+tt2) then begin
fndfld:=True;
End Else
Begin
if fields.Seek(tt) then begin
fndfld:=True;
End;
End;
if fndfld then begin
if empty(aliasname) then begin
if fields.s('ftype')='N' then begin
if fields.i('flen')<7 then begin
if fields.i('fdec')>0 then
res:='dbf.ff('''+fldname+''','+repval+')'
else
res:='dbf.ff('''+fldname+''','+repval+')'; { S/B .ii( }
end else
res:='dbf.ff('''+fldname+''','+repval+')';
End Else
if fields.s('ftype')='L' then begin
res:='dbf.bb('''+fldname+''','+repval+')';
End Else
if fields.s('ftype')='D' then begin
res:='dbf.dd('''+fldname+''','+repval+')';
End Else
if fields.s('ftype')='C' then begin
res:='dbf.ss('''+fldname+''','+repval+')';
End Else Begin
res:='dbf.XX('''+fldname+''','+repval+')';
End;
End Else
Begin
if fields.s('ftype')='N' then begin
if fields.i('flen')<7 then begin
if fields.i('fdec')>0 then
res:=aliasname+'.ff('''+fldname+''','+repval+')'
else
res:=aliasname+'.ff('''+fldname+''','+repval+')'; { S/B .ii( }
end else
res:=aliasname+'.ff('''+fldname+''','+repval+')';
End Else
if fields.s('ftype')='L' then begin
res:=aliasname+'.bb('''+fldname+''','+repval+')';
End Else
if fields.s('ftype')='D' then begin
res:=aliasname+'.dd('''+fldname+''','+repval+')';
End Else
if fields.s('ftype')='C' then begin
res:=aliasname+'.ss('''+fldname+''','+repval+')';
End Else Begin
res:=aliasname+'.XX('''+fldname+''','+repval+')';
End;
End;
End Else
Begin
if empty(aliasname) then begin
res:='dbf.ss('''+fldname+''','+repval+')';
End Else
Begin
res:=aliasname+'.XX('''+fldname+''','+repval+')';
End;
End;
End;
Result:=res;
end;
function oDL.argchk(orgstr,srchfor,has0arg,
has1arg,has2arg:string):string;
{ for all occurances in "orgstr" }
{ if "srchfor" found with 0 args, substitute "has0arg" }
{ if "srchfor" found with 1 args, substitute "has1arg" }
{ if "srchfor" found with 2 args, substitute "has2arg" }
{ if "srchfor" found with 3 args, substitute "has3arg" }
var starts,ennds,firstparen,lastparen,argsplit,ii,ll:integer;
parencnt,argcnt,yy,zz:integer;
upto,after,afterdot,targ1,targ2,dstt,tt3:string135;
noparm0,noparm1,noparm2,hitparen,inarray:boolean;
begin
noparm0:=False;
noparm1:=False;
noparm2:=False;
ii:=pos('.',has0arg);
afterdot:='';
if ii>1 then begin
afterdot:=Copy(has0arg,ii,30);
ii:=pos('~',afterdot);
if ii>1 then begin
afterdot:=Copy(afterdot,1,ii-1);
End;
End;
if pin('~',has0arg) then begin
noparm0:=True;
has0arg:=Copy(has0arg,1,length(has0arg)-1);
End;
if pin('~',has1arg) then begin
noparm1:=True;
has1arg:=Copy(has1arg,1,length(has1arg)-1);
End;
if pin('~',has2arg) then begin
noparm2:=True;
has2arg:=Copy(has2arg,1,length(has2arg)-1);
End;
starts:=pos(srchfor,orgstr);
While starts>0 do begin
DoEvents2;
ennds:=0;
firstparen:=0;
lastparen:=0;
argsplit:=0;
parencnt:=0;
ll:=length(orgstr);
hitparen:=False;
inarray:=False;
for ii:=starts to ll do begin
DoEvents2;
if Copy(orgstr,ii,1)='(' then begin
hitparen:=True;
if firstparen=0 then begin
firstparen:=ii;
End;
pp(parencnt);
End;
if Copy(orgstr,ii,1)='[' then begin
inarray:=True;
End;
if Copy(orgstr,ii,1)=']' then begin
inarray:=False;
End;
if (Not inarray) And (Copy(orgstr,ii,1)=',') then begin
if argsplit=0 then begin
argsplit:=ii;
End;
End;
if Copy(orgstr,ii,1)=')' then begin
parencnt:=parencnt-1;
if (hitparen) And (parencnt=0) then begin
lastparen:=ii;
ennds:=ii;
break;
End;
End;
End;
{ pars string }
upto:='';
after:='';
if starts>1 then begin
upto:=Copy(orgstr,1,starts-1);
End;
if (ennds<ll) And (ennds>0) then begin
after:=Copy(orgstr,ennds+1,ll);
End;
targ1:='';
targ2:='';
{ get length of argument area }
ii:=lastparen-firstparen-1;
argcnt:=0;
if ii>0 then begin
if argsplit>0 then begin
argcnt:=2;
{ has two arguments }
targ1:=Copy(orgstr,firstparen+1,argsplit-firstparen-1);
targ2:=Copy(orgstr,argsplit+1,lastparen-argsplit-1);
End Else
Begin
argcnt:=1;
{ only one argument }
targ1:=Copy(orgstr,firstparen+1,lastparen-firstparen-1);
End;
End;
{ change to new method for Delphi }
{ delete surrounding quote marks }
yy:=pos('''',targ1);
if yy>0 then begin
targ1:=Copy(targ1,2,30);
yy:=pos('''',targ1);
if yy>0 then begin
targ1:=Copy(targ1,1,yy-1);
End;
End;
if argcnt=0 then begin
orgstr:=upto+has0arg+after;
End Else
if argcnt=1 then begin
if pin('SKIP',upper(srchfor)) then begin
if (pin('''',orgstr)) then begin
orgstr:=upto+targ1+'.Skip'+after;
End Else
Begin
orgstr:=upto+'dbf.Skip2('+targ1+')'+after;
End;
End Else
Begin
if noparm1 then begin
orgstr:=upto+targ1+afterdot+after;
End Else
Begin
orgstr:=upto+'dbf'+afterdot+'('+targ1+')'+after;
End;
End;
End Else
if argcnt=2 then begin
orgstr:=upto+has2arg+'('+targ2+')'+after;
End;
starts:=pos(srchfor,orgstr);
End;
Result:=orgstr;
end;
End.